﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Data;
using System.Collections;

namespace Maestro_Proveedores.clases.almacen
{
    class Demanda
    {

        /// <summary>
        /// Funcion que realiza el calculo previo a la demanda
        /// Se buscan todas las transacciones (HIST_SALIDAS)para cada material
        /// Se depura la fecha de la demanda 
        /// y se depuran y consolidan las devoluciones encontradas en las salidas
        /// </summary>
        /// 

        public string generarDemandaMateriales(string almacen, DateTime fechaUltimoReporte)
        {
            string mensaje = string.Empty;

            _Maestro_Proveedores_CORPORATIVADataSet.ALM_STOCKDataTable alm_STOCKDataTable = new _Maestro_Proveedores_CORPORATIVADataSet.ALM_STOCKDataTable();
            _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_STOCKTableAdapter aLM_STOCKTableAdapter = new Maestro_Proveedores._Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_STOCKTableAdapter();

            //se consultan todos los materiales de stock para el almacen
            aLM_STOCKTableAdapter.FillByAlmacen(alm_STOCKDataTable, almacen);

            #region Se procede a realizar el pronostico para cada material que se encuentre en el datatable
            // valido que la tabla tenga informacion para evaluar

            if (alm_STOCKDataTable.Count != 0)
            {

                #region Consulta de transacciones por material
                //se recorren todos los registros del datatable de materiales 

                DateTime fechaActual = DateTime.Now;

                //Se genera el reporte a partir del siguiente dia (+1) de la fecha del ultimo reporte
                decimal fechaIni = decimal.Parse(MAESTROS.ClassVarios.FechaMAPIC(fechaUltimoReporte.AddDays(1)));
                decimal fechaFin = decimal.Parse(MAESTROS.ClassVarios.FechaMAPIC(fechaActual));

                //if (almacen.Equals("S01"))
                //    almacen = "001";
                //else
                //    almacen = "002";


                foreach (_Maestro_Proveedores_CORPORATIVADataSet.ALM_STOCKRow alm_STOCKRow in alm_STOCKDataTable)
                {
                    MAPICS.MAPICSDataSet.HIST_SALIDASDataTable hist_SALIDASDataTable = new MAPICS.MAPICSDataSet.HIST_SALIDASDataTable();
                    MAPICS.MAPICSDataSetTableAdapters.HIST_SALIDASTableAdapter hist_SALIDASTableAdapter = new MAPICS.MAPICSDataSetTableAdapters.HIST_SALIDASTableAdapter();

                    //hist_SALIDASTableAdapter.FillByFechasAlmacen(hist_SALIDASDataTable, almacen, alm_STOCKRow.COD_ITEM, fechaIni, fechaFin);
                    
                    if (almacen.Equals("001")) {
                        hist_SALIDASTableAdapter.FillBySalidasGeneralMamonal(hist_SALIDASDataTable, alm_STOCKRow.COD_ITEM, fechaIni, fechaFin);
                    }
                    else if (almacen.Equals("002")) {
                        hist_SALIDASTableAdapter.FillBySalidasGeneralBocagrande(hist_SALIDASDataTable, alm_STOCKRow.COD_ITEM, fechaIni, fechaFin);
                    }
                    
                    if (hist_SALIDASDataTable.Count > 0)
                    {
                        List<decimal> devoluciones = new List<decimal>();

                        foreach (MAPICS.MAPICSDataSet.HIST_SALIDASRow hist_SALIDASRow in hist_SALIDASDataTable)
                        {
                            //Depuraciòn de fechas - al final la columna de fecha_req_produccion guarda la fecha ideal
                            if (hist_SALIDASRow.IsFECHA_REQ_PRODUCCIONNull() || hist_SALIDASRow.FECHA_REQ_PRODUCCION.ToString().Length < 7)
                            {
                                if (hist_SALIDASRow.IsFECHA_REQUISICIONNull() || hist_SALIDASRow.FECHA_REQUISICION.ToString().Length < 7)
                                {
                                    hist_SALIDASRow.FECHA_REQ_PRODUCCION = hist_SALIDASRow.FECHA_TRANSACCION;
                                }
                                else
                                {
                                    hist_SALIDASRow.FECHA_REQ_PRODUCCION = hist_SALIDASRow.FECHA_REQUISICION;
                                }
                            }


                            //se evaluan las cantidades negativas

                            if (hist_SALIDASRow.CANTIDAD < 0)
                            {
                                devoluciones.Add(hist_SALIDASRow.CANTIDAD);
                                hist_SALIDASRow.Delete();
                            }
                        }

                        //se confirman los registros eliminados
                        hist_SALIDASDataTable.AcceptChanges();

                        // se evaluan todas las cantidades negativas que existieron y se elimina la contraparte positiva para no alterar la demanda
                        foreach (decimal cantidad in devoluciones)
                        {
                            foreach (MAPICS.MAPICSDataSet.HIST_SALIDASRow hist_SALIDASRow in hist_SALIDASDataTable)
                            {
                                if (hist_SALIDASRow.CANTIDAD == (cantidad * -1))
                                {
                                    hist_SALIDASRow.Delete();
                                    break;
                                }
                            }
                            hist_SALIDASDataTable.AcceptChanges();
                        }


                        //hist_SALIDASDataTable.AcceptChanges();
                        //calcular el numero de la semana
                        foreach (MAPICS.MAPICSDataSet.HIST_SALIDASRow hist_SALIDASRow in hist_SALIDASDataTable)
                        {
                            if (!hist_SALIDASRow.IsFECHA_REQ_PRODUCCIONNull())
                            {
                                DateTime fechaReqProduccion = MAESTROS.ClassVarios.FechaMAPIC((hist_SALIDASRow.FECHA_REQ_PRODUCCION.ToString()));
                                DateTime fechaCreacion = MAESTROS.ClassVarios.FechaMAPIC((hist_SALIDASRow.FECHA_TRANSACCION.ToString()));
                                DateTime fechaDemanda;

                                // se evalua que la fecha de la demanda este correcta
                                if (fechaReqProduccion.Year != fechaCreacion.Year )
       
                                {
                                    fechaDemanda = fechaCreacion;
                                }
                                else if (fechaReqProduccion.Year == fechaCreacion.Year && fechaReqProduccion.Month>fechaCreacion.Month)
                                {
                                     fechaDemanda = fechaCreacion;
                                }else{
                                    fechaDemanda = fechaReqProduccion;
                                }

                                int numSemana = CultureInfo.CurrentUICulture.Calendar.GetWeekOfYear(fechaDemanda, CalendarWeekRule.FirstDay, fechaDemanda.DayOfWeek);
                                
                                hist_SALIDASRow.SEMANA = hist_SALIDASRow.COD_ALMACEN+"-"+fechaDemanda.Year + "-" + numSemana.ToString();
                                
                            }
                        }
                        hist_SALIDASDataTable.AcceptChanges();

                        //se agrupan segun la semana y se guarda en una tabla
                        //se  recorre las transacciones se agrupan y se guardan en el datatable ALM_DEMAND
                        //parametros de agrupacion
                        string[] aggregate_columns = new string[] { "sumCANTIDAD" };
                        string[] aggregate_functions = new string[] { "sum(CANTIDAD)" };
                        Type[] column_types = new Type[] { typeof(decimal) };
                        string[] group_by_columns = new string[] { "SEMANA" };

                        //
                        DataTable tabla = MAESTROS.ClassVarios.GroupBy(hist_SALIDASDataTable, aggregate_columns, aggregate_functions, column_types, group_by_columns);

                        _Maestro_Proveedores_CORPORATIVADataSet.ALM_DEMANDADataTable alm_DEMANDADataTable = new _Maestro_Proveedores_CORPORATIVADataSet.ALM_DEMANDADataTable();
                        _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_DEMANDATableAdapter alm_DEMANDATableAdapter = new Maestro_Proveedores._Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_DEMANDATableAdapter();

                        foreach (DataRow fila in tabla.Rows)
                        {
                            _Maestro_Proveedores_CORPORATIVADataSet.ALM_DEMANDARow alm_DEMANDARow = alm_DEMANDADataTable.NewALM_DEMANDARow();
                            alm_DEMANDARow.COD_ITEM = alm_STOCKRow.COD_ITEM;
                            alm_DEMANDARow.DESCRIPCION = hist_SALIDASDataTable.Rows[0]["DES_ITEM"].ToString();
                            alm_DEMANDARow.COD_CLASE = alm_STOCKRow.COD_CLASE;
                            alm_DEMANDARow.CLASE = alm_STOCKRow.CLASE;
                            alm_DEMANDARow.COD_UNIDAD_MEDIDA = hist_SALIDASDataTable.Rows[0]["COD_UNIDAD_MEDIDA"].ToString();
                            alm_DEMANDARow.UNIDAD_MEDIDA = hist_SALIDASDataTable.Rows[0]["UNIDAD_MEDIDA"].ToString();
                             
                            alm_DEMANDARow.SEMANA = fila["SEMANA"].ToString();
                            alm_DEMANDARow.DEMANDA = decimal.Parse(fila["sumCANTIDAD"].ToString());
                            string[] temp = alm_DEMANDARow.SEMANA.Split('-');
                            alm_DEMANDARow.COD_ALMACEN = temp[0];
                            alm_DEMANDARow.ANIO_SEMANA = int.Parse(temp[1]);
                            alm_DEMANDARow.NUM_SEMANA = int.Parse(temp[2]);
                            //se agrega el nuevo registro
                            alm_DEMANDADataTable.AddALM_DEMANDARow(alm_DEMANDARow);
                        }
                        try
                        {
                            //se guarda la demanda de materiales consolidada, recien generada                            
                            alm_DEMANDATableAdapter.Update(alm_DEMANDADataTable);
                            

                        }
                        catch (Exception ex)
                        {
                            //
                        }
                    }
                }

                DateTime final = DateTime.Now;
                TimeSpan duracion = final - fechaActual;
                double segundosTotales = duracion.TotalSeconds;
                int minutos = duracion.Minutes;
                int segundos = duracion.Seconds;
                mensaje = "Total:" + minutos + ":" + segundosTotales.ToString() + " Segundos:" + segundos;
                //MessageBox.Show("Total:" + minutos + ":" + segundosTotales.ToString() + " Segundos:" + segundos);
                //fin control de tiempo
                #endregion
                // se guarda la fecha del nuevo reporte en la tabla ALM_DEMAN_HIST
                Maestro_Proveedores._Maestro_Proveedores_CORPORATIVADataSet.ALM_DEMANDA_HISTDataTable alm_DEMANDA_HISTDataTable = new _Maestro_Proveedores_CORPORATIVADataSet.ALM_DEMANDA_HISTDataTable();
                Maestro_Proveedores._Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_DEMANDA_HISTTableAdapter alm_DEMANDA_HISTTableAdapter = new Maestro_Proveedores._Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_DEMANDA_HISTTableAdapter();
                alm_DEMANDA_HISTDataTable.AddALM_DEMANDA_HISTRow(almacen, DateTime.Now.Date);
                alm_DEMANDA_HISTTableAdapter.Update(alm_DEMANDA_HISTDataTable);
            }
            #endregion

            return mensaje;
        }

        /// <summary>
        /// Funcion que recorre c/u de los materiales de stock, consulta la demanda calculada para cada material y 
        /// retorna un listado listo para realizar el pronostico
        /// </summary>

        public ArrayList consultarMaterialesStockconDemanda(bool esGeneral, string codClase, string almacen, DateTime fechaUltimoReporte)
        {

            ArrayList listadoMateriales = new ArrayList();

            //se consultan los materiales de stocck

            _Maestro_Proveedores_CORPORATIVADataSet.ALM_STOCKDataTable alm_STOCKDataTable = new _Maestro_Proveedores_CORPORATIVADataSet.ALM_STOCKDataTable();
            _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_STOCKTableAdapter aLM_STOCKTableAdapter = new Maestro_Proveedores._Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_STOCKTableAdapter();

            //El usuario selecciona una consulta general
            if (esGeneral)
            {
                aLM_STOCKTableAdapter.FillByAlmacen(alm_STOCKDataTable, almacen);
            }
            //El usuario selecciono por grupo
            else
            {
                //Se obtiene la clase=grupo que eligio el usuario
                aLM_STOCKTableAdapter.FillByAlmacenClase(alm_STOCKDataTable, codClase, almacen);
            }

            #region Se prodece a realizar el listado de materiales,y se busca la demanda para cada material
            // valido que la tabla tenga informacion para evaluar

            if (alm_STOCKDataTable.Count != 0)
            {
                // para cada material de stock se instancia un objeto (materialStockDemanda) se consulta la demanda y se arma el listado
                _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_DEMANDATableAdapter aLM_DEMANDATableAdapter = new Maestro_Proveedores._Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_DEMANDATableAdapter();
                _Maestro_Proveedores_CORPORATIVADataSet.ALM_DEMANDADataTable alm_DEMANDADataTable = new _Maestro_Proveedores_CORPORATIVADataSet.ALM_DEMANDADataTable();
           
                foreach (_Maestro_Proveedores_CORPORATIVADataSet.ALM_STOCKRow alm_STOCKRow in alm_STOCKDataTable)
                {
                    MaterialStockDemanda materialStockDemanda = new MaterialStockDemanda();
                    //CONSULTAR SI EL MATERIAL TIENE HISTORICO DE DEMANDA
                    
                    aLM_DEMANDATableAdapter.FillConsultarMaterial(alm_DEMANDADataTable, alm_STOCKRow.COD_ITEM, alm_STOCKRow.COD_ALMACEN);

                    materialStockDemanda.Almacen = alm_STOCKRow.COD_ALMACEN;
                    materialStockDemanda.Clase = alm_STOCKRow.CLASE;
                    materialStockDemanda.Cod_item = alm_STOCKRow.COD_ITEM;
                     
                    //se evalua que el material presente demanda, o por lo menos 30 semanas de demanda
                    
                    //identifica cual materialS tiene Una anomalia en elsistema
                    if (alm_DEMANDADataTable.Count > 1)
                    {
                        String Info = "el material presenta error en el sistema, para el mismo codigo en el sistema";
                    }


                    if (alm_DEMANDADataTable.Count <=0)
                    {
                        materialStockDemanda.ConDemanda = false;
                    }
                    else {
                        materialStockDemanda.ConDemanda = true;
                        //se consulta el material para obtener informacion del material
                        string cod_unid_medida = alm_DEMANDADataTable.Rows[0]["COD_UNIDAD_MEDIDA"].ToString();
                        string unid_medida = alm_DEMANDADataTable.Rows[0]["UNIDAD_MEDIDA"].ToString();
                        string desc_material = alm_DEMANDADataTable.Rows[0]["DESCRIPCION"].ToString(); 
                        // se llamma al metodo generarEsquemaSemanas que retorna un arreglo que contiene las 104 semanas
                        materialStockDemanda.DemandaMaterial = generarEsquemaRegSemanas(materialStockDemanda.Almacen, alm_STOCKRow.COD_ITEM, alm_STOCKRow.COD_CLASE,cod_unid_medida,unid_medida,desc_material);
                    }

                    // se agrega el objeto materialStockDemanda al arreglo global
                    listadoMateriales.Add(materialStockDemanda);
                }
            }

            #endregion
            
            return listadoMateriales;

        }

        /// <summary>
        /// Funcion que generar un listado de 104 semanas (2 años) y llenarlo a partir de una conulta en la tabla hist_demanda 
        /// </summary>
        /// 
        
        private ArrayList generarEsquemaRegSemanas(string almacen, string cod_item, string cod_clase,string cod_unid_medida,string unid_medida,string desc_material)
        {

            ArrayList listadoSemanas = new ArrayList();

            _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_DEMANDATableAdapter aLM_DEMANDATableAdapter = new Maestro_Proveedores._Maestro_Proveedores_CORPORATIVADataSetTableAdapters.ALM_DEMANDATableAdapter();

            //consultar total de semanas de consulta

            DateTime fechaFinal = DateTime.Now;
            DateTime fechaInicio = new DateTime((DateTime.Now.Year - 2), DateTime.Now.Month, DateTime.Now.Day);

            int semanaInicio = CultureInfo.CurrentUICulture.Calendar.GetWeekOfYear(fechaInicio, CalendarWeekRule.FirstDay, fechaInicio.DayOfWeek);
            int anioInicio = fechaInicio.Year;

            int semanaFin = CultureInfo.CurrentUICulture.Calendar.GetWeekOfYear(fechaFinal, CalendarWeekRule.FirstDay, fechaFinal.DayOfWeek);
            int anioFin = fechaFinal.Year;

            int totalSemanas = numeroSemanasAnio(anioInicio) + numeroSemanasAnio(anioFin);

            int refNumSemana = semanaInicio;
            int refAnio = anioInicio;

            for (int i = 1; i <= totalSemanas; i++)
            {
                Registro registroSemana = new Registro();
                registroSemana.Id_semana = refNumSemana;
                registroSemana.Cod_clase = cod_clase;
                registroSemana.Cod_material = cod_item;
                registroSemana.Semana = i;

                try
                {
                    object valo =aLM_DEMANDATableAdapter.ScalarQueryDemanda(almacen, refNumSemana, refAnio, cod_item);
                    
                    if (valo==null || string.IsNullOrEmpty(valo.ToString()))
                        registroSemana.Demanda = 0;
                    else
                        registroSemana.Demanda = int.Parse(valo.ToString());

                    registroSemana.Cod_unid_medida = int.Parse(cod_unid_medida);
                    registroSemana.Unid_medida = unid_medida;
                    registroSemana.Desc_material = desc_material;
                }
                catch (Exception ex) {
                    string mensaje = ex.Message;
                }

                listadoSemanas.Add(registroSemana);

                //se actualizan las referencias
                //revizo el maximo de semanas para cada año y si llega al final se actualiza semana y año
                int maxSemanas = numeroSemanasAnio(refAnio);

                //si llego a la semana maxima del año se pasa al siguiente año en la semana 1
                if (refNumSemana == maxSemanas)
                {
                    refAnio++;
                    refNumSemana = 1;
                }
                else
                {
                    refNumSemana++;
                }
            }
            return listadoSemanas;

        }

        /// <summary>
        /// Funcion que calcula el numero total de semanas por año
        /// </summary>
        /// 
        private int numeroSemanasAnio(int anio)
        {
            // Obtiene la instancia de calendario asociada al Actual CultureInfo
            CultureInfo myCI = CultureInfo.CurrentUICulture;
            Calendar myCal = myCI.Calendar;

            // Gets the DTFI properties required by GetWeekOfYear.
            CalendarWeekRule myCWR = myCI.DateTimeFormat.CalendarWeekRule;
            DayOfWeek myFirstDOW = myCI.DateTimeFormat.FirstDayOfWeek;
            DateTime LastDay = new System.DateTime(DateTime.Now.Year, 12, 31);
            int totalDias = myCal.GetWeekOfYear(LastDay, myCWR, myFirstDOW);
            return totalDias;
        }

        public DataTable generarReporte(ArrayList materialesDemanda, string nivelServicio)
        {

            DataTable aTable = new DataTable();
            //Se definen las columnas
            aTable.Columns.Add("CLASE", typeof(string));
            aTable.Columns.Add("CODIGO_ITEM", typeof(string));
            aTable.Columns.Add("DESCRIPCION_ITEM", typeof(string));
            aTable.Columns.Add("UNIDAD_MEDIDA", typeof(string));
            aTable.Columns.Add("ALMACEN", typeof(string));
            aTable.Columns.Add("ULT. PROVEEDOR", typeof(string));
            aTable.Columns.Add("TIEMPO DE ENTREGA (L) (Semanas)", typeof(string));
            aTable.Columns.Add("NIVEL DE SERVICIO (K)", typeof(string));
            aTable.Columns.Add("STOCK DE SEGURIDAD (IS o s)", typeof(string));
            aTable.Columns.Add("PERIODO DE REVISION (Semanas)", typeof(string));
            aTable.Columns.Add("INVENTARIO A LA MANO", typeof(string));
            //aTable.Columns.Add("INVENTARIO NETO", typeof(string));
            //aTable.Columns.Add("INVENTARIO EFECTIVO", typeof(string));
            aTable.Columns.Add("PRONOSTICO (Semanas)", typeof(string));
            //aTable.Columns.Add("ERROR DE PRONOSTICO", typeof(string));
            //aTable.Columns.Add("DESVIACION DEL ERROR DE PRONOSTICO", typeof(string));
            //aTable.Columns.Add("PEDIR", typeof(string));
            //aTable.Columns.Add("DEM. PRONOSTICADA EN EL TIEMPO DE REPOSICION + REVISION", typeof(string));
            aTable.Columns.Add("INVENTARIO MAXIMO", typeof(string));
            //aTable.Columns.Add("CANTIDAD A PEDIR", typeof(string));

            //se recorren los materiales disponibles y se calculan los campos 
            foreach (MaterialStockDemanda material in materialesDemanda)
            {
                Registro infoMaterial = new Registro();

                if (material.ConDemanda)
                {
                    infoMaterial = (Registro)material.DemandaMaterial[0];

                    DataRow dr;
                    dr = aTable.NewRow();
                    dr["CLASE"] = material.Clase;
                    dr["CODIGO_ITEM"] = material.Cod_item;
                    dr["DESCRIPCION_ITEM"] = infoMaterial.Desc_material;
                    dr["UNIDAD_MEDIDA"] = infoMaterial.Unid_medida;
                    dr["ALMACEN"] = material.Almacen;
                    dr["ULT. PROVEEDOR"] = consUltimoProveedor (material.Cod_item); ////// definir consulta ultimo proveedor
                    double LTP = calcularLTP(material.Cod_item, DateTime.Now);
                    dr["TIEMPO DE ENTREGA (L) (Semanas)"] = String.Format("{0:0.####}", LTP);
                    double K = calcularK(nivelServicio);
                    dr["NIVEL DE SERVICIO (K)"] = String.Format("{0:0.####}", K);
                    double error = calcularError(material.ModeloFinal.resNideal);
                    double stock = calcularStock(K, error, LTP);
                    dr["STOCK DE SEGURIDAD (IS o s)"] = String.Format("{0:0.##}", stock);
                    dr["PERIODO DE REVISION (Semanas)"] = "1";
                    double inventarioMano = calcularExistencias(material.Cod_item, material.Almacen);
                    dr["INVENTARIO A LA MANO"] = inventarioMano.ToString();
                    //dr["INVENTARIO NETO"] = "";     ////// definir consulta requisiciones por material+codigo (ultimo mes)
                    //dr["INVENTARIO EFECTIVO"] = ""; ////// definir consulta OC por material + codigo (ultimo mes)
                    dr["PRONOSTICO (Semanas)"] = material.ModeloFinal.resNideal.pronosticoN1;
                    //dr["ERROR DE PRONOSTICO"] = String.Format("{0:0.####}", error);
                    //dr["DESVIACION DEL ERROR DE PRONOSTICO"] = calcularDesviacionError(material.ModeloFinal.resNideal);

                    //if (inventarioMano < stock)
                    //    dr["PEDIR"] = "PEDIR";
                    //else
                    //    dr["PEDIR"] = "OK";

                    double demandaPronostico = calcularDemandaPronostico(LTP, material.ModeloFinal.resNideal.pronosticoN1);
                    //dr["DEM. PRONOSTICADA EN EL TIEMPO DE REPOSICION + REVISION"] = demandaPronostico.ToString();
                    if (stock > 0)
                    {
                        dr["INVENTARIO MAXIMO"] = stock + demandaPronostico;
                    }
                    else
                    {
                        dr["INVENTARIO MAXIMO"] = -1;
                    }
                    //dr["CANTIDAD A PEDIR"] = "";//pendiente calcular inventario efectivo
                    aTable.Rows.Add(dr);
                }
                //CASO EN EL CUAL EL MATERIAL NO PRESENTO NINGUNA DEMANDA, (POCOS CASOS PERO EXISTEN)
                else {

                    DataRow dr;
                    dr = aTable.NewRow();
                    dr["CLASE"] = material.Clase;
                    dr["CODIGO_ITEM"] = material.Cod_item;
                    dr["DESCRIPCION_ITEM"] = infoMaterial.Desc_material;
                    dr["UNIDAD_MEDIDA"] = infoMaterial.Unid_medida;
                    dr["ALMACEN"] = material.Almacen;
                    aTable.Rows.Add(dr);
                }

            }
            return aTable;
        }

        ///Funciones del reporte

        private double calcularLTP(string codArticulo, DateTime fechaFinal)
        {
            double leadTimePromedio = 0;
            //se consulta un a;o atras todas las ordenes de compra relacionadas al articulo
            DateTime fechaInicio = new DateTime((fechaFinal.Year - 1), fechaFinal.Month, fechaFinal.Day);

            MAPICS.MAPICSDataSet.INF_OCDataTable inf_OCDataTable = new MAPICS.MAPICSDataSet.INF_OCDataTable();

            inf_OCDataTable.FillCodMaterialesFechas(codArticulo, fechaInicio, fechaFinal);

            if (inf_OCDataTable.Count > 0)
            {

                double sumatoria = 0;
                //control
                ArrayList resultados = new ArrayList();

                foreach (MAPICS.MAPICSDataSet.INF_OCRow inf_OCRow in inf_OCDataTable)
                {
                    double diferencia = MAESTROS.ClassVarios.TotalDias(MAESTROS.ClassVarios.FechaMAPIC(inf_OCRow.FECHA.ToString()), MAESTROS.ClassVarios.FechaMAPIC(inf_OCRow.FECHA_ENTR_R.ToString()));
                    sumatoria += (diferencia - 1);

                    //control lead time
                    Registro reg = new Registro((int)inf_OCRow.FECHA_ENTR_R, (int)inf_OCRow.FECHA);
                    reg.Cod_clase = inf_OCRow.COD_OC;
                    reg.Cod_material = inf_OCRow.COD_ITEM;
                    reg.Et = diferencia - 1;
                    resultados.Add(reg);
                }

                //FileManager fileManager = new FileManager();
                //fileManager.generarArchivoControlLeadTime(resultados, "LDtime");

                int contador = inf_OCDataTable.Count;
                leadTimePromedio = sumatoria / contador;

                return leadTimePromedio / 7;
            }
            else
            {
                return -1;
            }
        }

        private double calcularK(string nivelServicio)
        {
            Maestro_Proveedores.clases.herramientas.Enums enums = new Maestro_Proveedores.clases.herramientas.Enums();
            double tempK = double.Parse(nivelServicio);
            double K = enums.retornarK(tempK / 100);
            return K;
        }

        private double calcularExistencias(string cod_item,string cod_almacen)
        {
            double existencias=0;

            MAPICS.MAPICSDataSet.UBIC_ARTDataTable ubic_ARTDataTable = new MAPICS.MAPICSDataSet.UBIC_ARTDataTable();
            MAPICS.MAPICSDataSetTableAdapters.UBIC_ARTTableAdapter ubic_ARTTableAdapter = new MAPICS.MAPICSDataSetTableAdapters.UBIC_ARTTableAdapter();
            ubic_ARTTableAdapter.FillByArticulo(ubic_ARTDataTable,cod_item);

            if (ubic_ARTDataTable.Count > 0)
            {
                foreach (MAPICS.MAPICSDataSet.UBIC_ARTRow ubic_ARTRow in ubic_ARTDataTable)
                {
                    if (ubic_ARTRow.ALMACEN.Equals(cod_almacen)) {
                        existencias=double.Parse(ubic_ARTRow.CAN_DISPONIBLE.ToString());
                    }
                }
                
            }
            return existencias;
        }

        private double calcularError(Resultado resNideal)
        {
            double error1 = 1.25333 * resNideal.MAD;
            double error2 = Math.Sqrt(resNideal.ECM);
            if (error1 < error2)
            {
                return error2;
            }
            else
            {
                return error1;
            }
        }

        private string calcularDesviacionError(Resultado resultado)
        {
            return String.Format("{0:0.##}", Math.Sqrt(resultado.ECM));
        }

        private double calcularStock(double K, double errorPronostico, double LTP)
        {
            if (LTP > 0)
            {
                return K * errorPronostico * Math.Sqrt(1 + LTP);
            }
            else {
                return -1;
            }
        }

        private double calcularDemandaPronostico(double LTP, double p)
        {
            return p * (LTP + 1);
        }

        private string consUltimoProveedor(string cod_item)
        {
            MAPICS.MAPICSDataSetTableAdapters.INF_OC_DETALLADATableAdapter inf_OC_DETALLADATableAdapter = new MAPICS.MAPICSDataSetTableAdapters.INF_OC_DETALLADATableAdapter();
            string cod_proveedor = inf_OC_DETALLADATableAdapter.Cod_Item_UltimoProveedor(cod_item);

            if (!string.IsNullOrEmpty(cod_proveedor))
            {
                MAPICS.MAPICSDataSet.PROVEEDORESDataTable pROVEEDORESDataTable = new MAPICS.MAPICSDataSet.PROVEEDORESDataTable();
                MAPICS.MAPICSDataSetTableAdapters.PROVEEDORESTableAdapter pROVEEDORESTableAdapter = new MAPICS.MAPICSDataSetTableAdapters.PROVEEDORESTableAdapter();
                pROVEEDORESTableAdapter.FillByID(pROVEEDORESDataTable, cod_proveedor);

                foreach (MAPICS.MAPICSDataSet.PROVEEDORESRow pROVEEDORESRow in pROVEEDORESDataTable)
                {
                    cod_proveedor = pROVEEDORESRow.RAZON_SOCIAL.ToString();
                }
            }
            else
            {
                cod_proveedor = "Sin Dato";
            }

            return cod_proveedor;
        }


        #region Consulta de requerimientos por material
        //MAPICS.MAPICSDataSet.DET_REQDataTable det_REQDataTable = new MAPICS.MAPICSDataSet.DET_REQDataTable();
        //MAPICS.MAPICSDataSetTableAdapters.DET_REQTableAdapter det_REQTableAdapter = new MAPICS.MAPICSDataSetTableAdapters.DET_REQTableAdapter();

        //det_REQTableAdapter.FillByCOD_ITEM(det_REQDataTable, "20015039");
        ////det_REQTableAdapter.fil

        //if (det_REQDataTable.Count > 0)
        //{
        //    foreach (MAPICS.MAPICSDataSet.DET_REQRow row in det_REQDataTable)
        //    {

        //    }
        //}
        #endregion
       
    }
}